home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume7 / forktest < prev    next >
Encoding:
Internet Message Format  |  1986-12-09  |  6.2 KB

  1. Subject:  v07i090:  Find security holes in shell-escapes
  2. Newsgroups: mod.sources
  3. Approved: mirror!rs
  4.  
  5. Submitted by: ihnp4!utzoo!hcr!hcrvx1!hugh
  6. Mod.sources: Volume 7, Issue 90
  7. Archive-name: forktest
  8.  
  9. I would like to submit the following program to mod.sources.  I hope
  10. that the comments are sufficient explanation.  I don't see that a
  11. manual is worthwhile.
  12.  
  13. I have run this program under System V and Version 7.  I have not
  14. tested it under BSD, but I know of no impediment.
  15.  
  16. With this program, I have found bugs in a number of UNIX System V
  17. utilities.  I am sure that BSD programs would be just as buggy, but
  18. I haven't tested them.  Here are some examples:
  19.  
  20. Programs that leave extra file descriptors open:
  21.      sdb ! command
  22.      mailx ~! command during message composition, and ! command (two extra)
  23.      mail ! command
  24.      rn ! or | command (5 extra!)
  25.      cu ~! command (one extra: number 5)
  26.  
  27. Programs that leave signals ignored:
  28.      mailx ~! command (SIGINT!)
  29.      rn ! and | commands (SIGEMT!?)
  30.  
  31. I think that this list shows that it is easy to get fork(2) wrong.
  32. I hope programmers will use ForkTest to catch this type of bug
  33. early.  Exercise for the reader: what can you scribble on with those
  34. extra file descriptors?
  35.  
  36. Hugh Redelmeier (416) 922-1937
  37. utzoo!hcr!hugh
  38.  
  39. [  I wrote the Makefile and README.  --r$  ]
  40. ----------CUT HERE----------
  41.  
  42. #! /bin/sh
  43. # This is a shell archive.  Remove anything before this line,
  44. # then unpack it by saving it in a file and typing "sh file".
  45. # If all goes well, you will see the message "End of shell archive."
  46. # Contents:  Makefile README forktest.c
  47. # Wrapped by rs@mirror on Wed Dec 10 13:44:46 1986
  48. PATH=/bin:/usr/bin:/usr/ucb; export PATH
  49. echo shar: extracting "'Makefile'" '(52 characters)'
  50. if test -f 'Makefile' ; then 
  51.   echo shar: will not over-write existing file "'Makefile'"
  52. else
  53. sed 's/^X//' >Makefile <<'@//E*O*F Makefile//'
  54. X
  55. Xforktest:    forktest.c
  56. X    $(CC) $(CFLAGS) -o forktest
  57. X
  58. @//E*O*F Makefile//
  59. if test 52 -ne "`wc -c <'Makefile'`"; then
  60.     echo shar: error transmitting "'Makefile'" '(should have been 52 characters)'
  61. fi
  62. fi # end of overwriting check
  63. echo shar: extracting "'README'" '(253 characters)'
  64. if test -f 'README' ; then 
  65.   echo shar: will not over-write existing file "'README'"
  66. else
  67. sed 's/^X//' >README <<'@//E*O*F README//'
  68. X
  69. X[  This program is designed to be called by programs that allow
  70. X   shell escapes.  It prints out the argc,argv parameters, and
  71. X   lists the disposition of signals, alarm calls, etc.  The fun
  72. X   part is when it lists the open file descriptors...  -r$ ]
  73. @//E*O*F README//
  74. if test 253 -ne "`wc -c <'README'`"; then
  75.     echo shar: error transmitting "'README'" '(should have been 253 characters)'
  76. fi
  77. fi # end of overwriting check
  78. echo shar: extracting "'forktest.c'" '(3059 characters)'
  79. if test -f 'forktest.c' ; then 
  80.   echo shar: will not over-write existing file "'forktest.c'"
  81. else
  82. sed 's/^X//' >forktest.c <<'@//E*O*F forktest.c//'
  83. X/* Fork Test: display args, open files, signals, etc.
  84. X *
  85. X * Simple as this program is, it has found bugs in the
  86. X * way a number of programs fork off children.  To test
  87. X * how a program is invoking its children, run this
  88. X * program as a child.
  89. X *
  90. X * Generally, processes should be created with:
  91. X *
  92. X * - a reasonable arg count & list
  93. X * - arg 0 should look like the name of the command
  94. X *
  95. X * - real and effective UIDs and GIDs should be reasonable.
  96. X *   Beware setuid programs that fork children!
  97. X *
  98. X * - no pending alarm.  Version 7 apparently does not
  99. X *   reset alarms upon an exec!
  100. X *
  101. X * - file descriptors 0 (STDIN), 1 (STDOUT), and 2 (STDERR)
  102. X *   opened reasonably
  103. X * - all other file descriptors closed (this program will
  104. X *   describe all open channels)
  105. X *
  106. X * - all signals (except SIGKILL) set to SIG_DFL (this
  107. X *   program will print all signals set otherwise)
  108. X *
  109. X * The output is fairly simple to understand.  When in
  110. X * doubt, read the code (and a UNIX manual: exec(2),
  111. X * getuid(2), alarm(2), signal(2), stat(2)).
  112. X *
  113. X * Room for Improvement:
  114. X *
  115. X * - strings should be printed in a way that shows funny characters.
  116. X * - show misc. other bits of state
  117. X *    - PID (who cares?)
  118. X *    - umask
  119. X *    - ulimit (System V)
  120. X *    - stty settings of open TTYs
  121. X *
  122. X * Copyright (c) 1986 March 11  D. Hugh Redelmeier
  123. X *
  124. X * This program may be distributed and used without restriction.
  125. X */
  126. X
  127. X#include <stdio.h>
  128. X
  129. Xextern unsigned alarm();    /* should be unsigned, but may be int */
  130. X
  131. X#include <sys/types.h>
  132. X#include <sys/stat.h>
  133. X
  134. Xstruct stat sb;
  135. X
  136. X#include <errno.h>
  137. Xextern int errno;
  138. Xextern char *sys_errlist[];
  139. X
  140. X#include <signal.h>
  141. X
  142. Xint (*signal())();
  143. X
  144. Xmain(argc, argv, envp)
  145. Xint argc;
  146. Xchar **argv, **envp;
  147. X{
  148. X    register int i;
  149. X    unsigned al = alarm(0);    /* get it while it is hot */
  150. X
  151. X    printf("%d arg(s):", argc);
  152. X    for (i=0; i<argc; i++)
  153. X        if (argv[i] == NULL)
  154. X            printf(" NULL!");
  155. X        else
  156. X            printf(" \"%s\"", argv[i]);
  157. X    printf("\n");
  158. X    if (argv[argc] != NULL)
  159. X        printf("Arg list is not ended with a NULL!\n");
  160. X
  161. X    printf("Real UID = %d, GID = %d; Effective UID = %d, GID = %d.\n",
  162. X        getuid(), getgid(), geteuid(), getegid());
  163. X
  164. X    if (al)
  165. X        printf("Alarm set to go off in %u seconds.\n", al);
  166. X
  167. X    printf("File Descriptors:\n");
  168. X    for (i=0; i!=40; i++)    /* I hope 40 is enough. */
  169. X        if (fstat(i, &sb) == -1) {
  170. X            if (errno != EBADF)
  171. X                printf("\t%d error: %s\n", i, sys_errlist[errno]);
  172. X        } else {
  173. X            printf("\t%d: dev=%d, ino=%d, perm=0%04o, ",
  174. X                i, sb.st_dev, sb.st_ino, sb.st_mode&07777);
  175. X            switch (sb.st_mode & S_IFMT) {
  176. X            case S_IFREG:
  177. X                printf("pipe or regular file\n");
  178. X                break;
  179. X            /* extend as desired */
  180. X            default:
  181. X                printf("IFMT=0%o\n", sb.st_mode>>12);
  182. X                break;
  183. X            }
  184. X        }
  185. X
  186. X    printf("Signals:\n");
  187. X    for (i=1; i!=40; i++) {    /* I hope 40 is enough. */
  188. X        register int n = (int) signal(i, SIG_IGN);
  189. X        switch (n) {
  190. X        case -1:
  191. X        case SIG_DFL:
  192. X            break;
  193. X        case SIG_IGN:
  194. X            printf("\t%d: SIG_IGN\n", i);
  195. X            break;
  196. X        default:
  197. X            printf("\t%d: %d\n", i, n);
  198. X            break;
  199. X        }
  200. X    }
  201. X
  202. X    printf("Environment:\n");
  203. X    for (i=0; envp[i]!=NULL; i++)
  204. X        printf("\t\"%s\"\n", envp[i]);
  205. X
  206. X    exit(0);
  207. X}
  208. @//E*O*F forktest.c//
  209. if test 3059 -ne "`wc -c <'forktest.c'`"; then
  210.     echo shar: error transmitting "'forktest.c'" '(should have been 3059 characters)'
  211. fi
  212. fi # end of overwriting check
  213. echo shar: "End of shell archive."
  214. exit 0
  215.